#include "GInterpreter.h"

GInterpreter::GInterpreter(QObject *parent) : QObject(parent)
{

}

int GInterpreter::interpret(QString gcode, MotionPath *path)
{
    _gcode = gcode;
    _path = path;
    settings.reset();
    _path->reset();
    QStringList codes = gcode.split("\n");
    for (int i = 0; i < codes.size(); ++i)
    {
        int parseRet = parse(codes.at(i));
//        qDebug() << "parse:" << parseRet << block.items;
        if (parseRet)
            return parseRet;
        int execRet = execute();
        if (execRet)
            return execRet;
    }
    return 0;
}

int GInterpreter::parse(QString line)
{
    block.reset();
    return read_items(line);
}

int GInterpreter::read_items(QString line)
{
    int i = 0;
    while (i < line.size())
    {
        int ret = read_one_item(line, i);
        if (ret)
            return ret;
    }
    return 0;
}

int GInterpreter::read_one_item(QString line, int& count)
{
    QString numbers = "1234567890.-+";
    QChar first = line.at(count);
    if (!first.isLetter())
        return 1;
    count++;
    int start = count;
    while (count < line.size())
    {
        if (numbers.contains(line.at(count)))
            count++;
        else
            break;
    }
    QString value;
    for (int i = start; i < count; ++i)
    {
        value.append(line.at(i));
    }
    bool valid;
    qreal v = value.toDouble(&valid);
    if (!valid)
        return 2;
    block.items.insert(first, v);
    return 0;
}

int GInterpreter::execute()
{
    if (!block.items.contains('G')) // No G code
        return 3;
    if (!block.items.contains('X') &&
            !block.items.contains('Y')) // No axis values
        return 4;
    if (block.items.value('G') == 1) // Line
    {
        LineNode* line = new LineNode(block.items.value('X', 0.0),
                                      block.items.value('Y', 0.0));
        _path->addPathNode(line);
    }
    return 0;
}
